#coding=utf-8

from flask import Flask, render_template,request,jsonify,make_response,Response
import json
from mongodb import *
from pymongo import MongoClient
import demjson
import math
from xpinyin import Pinyin
from io import StringIO
import pandas as pd
import threading 
from concurrent.futures import ThreadPoolExecutor
from static.configfile.config import *
import EventData
executor =ThreadPoolExecutor(2)

p = Pinyin() 
ping_list = { "weixin": "微信", "weibo": "微博", "baijiahao": "百家号" ,"baidu": "百度"}
# ping_list = { "weixin": "微信", "weiboAPI": "微博API","weiboScrapy": "微博Scrapy", "baijiahao": "百家号" ,"baidu": "百度"}
pingtai = { "微信": "weixin", "微博API": "weiboAPI", "微博Scrapy": "weiboScrapy","百家号": "baijiahao","百度": "baidu" }
    
import os
baseDir = os.path.join(os.getcwd(), "file")
# 任务卡片需要展示的字段
show = ['name', 'source', 'complete', 'cycle', 'status', 'savetime']

mongo_url_to_db = mongo_url_to_db  # 传入DB
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/test')
def test():
    return render_template('test.html')

@app.route('/<name>/dataset',methods=["GET"])
def data(name):
    return render_template('dataset.html',name=name)

@app.route('/<name>/eventstudy',methods=["GET"])
def eventstudy(name):
    return render_template('EventStudy.html',name=name)

@app.route('/gettask',methods=["GET","POST"])
def get_Task():
    size = 9; #每页显示九条数据
    if request.method == "GET":
        response = {}
        data = []
        # print("current")
        # print(request.args.get('current'))
        current = int(request.args.get('current'))
        client =MongoClient(mongo_url_to_db)
        collection = client["Task"]["task"]
        canshu = {}
        status = request.args.get('status')
        if status == "":
            canshu["status"] = {"$nin":["delete"]}
        else:
            canshu["status"] = status
        # all_data_num = len(list(collection.find(canshu)))
        all_data_num = collection.count_documents(canshu)
        # print("all_num")
        # print(all_data_num)
        page = math.ceil(all_data_num / size) #总共可以分的页数
        # for key,value in request.args.items():
        #     canshu[key] = value
        # print(canshu)
        with collection.find(canshu,{'_id':0,'timestamp':0},no_cursor_timeout=True).skip((current-1)*size).limit(size).sort("savetime", -1) as ret:
            for r in ret:
                
                d = r["canshu"]
                for k,v in r.items():
                    if k in show:
                        d[k] = v
                data.append(d)
        client.close()
        # print(data)
        response["data"] = data
        response["page"] = page
        response["current"] = current
        response["status"] = 200
    return response

@app.route('/addtask',methods=["POST"])
def add_Task():
    flag = 0 #0代表任务为新创建的，1代表任务为新编辑的
    item = {}
    item["name"] = str(request.json.get('name'))
    item["source"] = str(request.json.get('source'))
    task = find_task(item)
    if task:
        flag = 1
    data ={}
    try:
        if flag==0:
            # 获取发送请求的主机ip
            ip = request.remote_addr
            item["host"]  = ip
            item["process"] = "未知"
            item["complete"] = 0
            item["status"] = "stop"
            canshu = request.json.get('canshu')
            canshu["dbname"] = "doc_"+str(p.get_pinyin(item["name"],""))
            # print(canshu["dbname"])
            # 在js端json的key只能使用双引号，但是从前端接收来的dict数据的key使用的是单引号，这里需要将单引号替换为双引号，以便在前端处理
            item['canshu'] = canshu
            item["cycle"] = str(request.json.get('cycle'))
            item["cyclic"] = str(request.json.get('cyclic'))
            insert_task(item)
        elif flag==1:
            update = {}
            dbname = "doc_"+str(p.get_pinyin(item["name"],""))
            # print(',"dbname":"'+dbname+'"}')
            temp = request.json.get('canshu')
            temp["dbname"] = dbname
            update["canshu"] =  temp
            # print(update["canshu"])
            update["cycle"] = str(request.json.get('cycle'))
            update["cyclic"] = str(request.json.get('cyclic'))
            update_task(item, update)
        data["status"] = 200
    except Exception as e:
        data["status"] = str(e)
    return data

# 更新任务状态,并决定爬虫脚本的启动和停止
@app.route("/setStatus",methods=["POST"])
def set_Status():
    update ={}
    item={}
    item["name"] = str(request.json.get('name'))
    item["source"] = str(request.json.get('source'))
    update["status"] = str(request.json.get('status'))
    data = {}
    
    # 查找点击的任务详情
    task = find_task(item)
    
    if update["status"] == "stop":
        print("该任务需要被停止")
    else:
        print(update["status"])

    try:
        update_task(item,update)
        data["status"] = 200
    except:
        data["status"] = 404
    return data

# 编辑任务信息
@app.route("/getDetail", methods=["GET"])
def get_Detail():
    update ={}
    item={}
    for k,v in request.args.items():
        item[k]=v
    task = find_task(item)
    print("---------------")
    print(task)
    return task

@app.route('/getData',methods=["GET"])
def get_Data():
    size = 50; #每页显示二十条数据
    response = {}
    canshu = {"type":"original"}
    data = []
    mainText = request.args.get('kwd')
    if len(mainText) != 0:
        canshu = demjson.decode(mainText)
    current = int(request.args.get('current'))
    dbname = "doc_"+str(p.get_pinyin(request.args.get('dbname'),""))
    client =MongoClient(mongo_url_to_db)
    collection =client["Task"][dbname]
    all_data_num = collection.count_documents(canshu)
    page = math.ceil(all_data_num / size) #总共可以分的页数
    with collection.find(canshu,{'_id':0,'timestamp':0},no_cursor_timeout=True).skip((current-1)*size).limit(size) as ret:
        for r in ret:
            r["pubTime"] = time.strftime("%Y-%m-%d %H:%M",time.localtime(r["pubTime"]))
            
            data.append(r)
    response["data"] = data
    response["current"] = current
    response["page"] = page
    response["status"] = 200
    return response 

@app.route('/down',methods=['GET'])
def get_file():
    data = []
    filename = request.args.get("fileName")
    fs = str(p.get_pinyin(filename,""))
    print(fs)
    pathname = os.path.join(baseDir, fs)
    def generate():
        with open(pathname, 'rb') as target_file:
            while True:
                chunk = target_file.read(1024 * 1024)  # 每次读取1M
                if not chunk:
                    break
                yield chunk
    # response = make_response(stream.getvalue())
    response = Response(generate(), mimetype='text/'+filename.split(".")[-1],content_type='application/octet-stream') 
    # response.headers["Content-type"] = "text/"+filetype
    response.headers["Content-Disposition"] = "attachment; filename={}".format("down."+filename.split(".")[-1])
    # response.headers["Connection"] = "keep-alive"
    return response
    # return Response(generate(filetype), mimetype='text/'+filetype,content_type='application/octet-stream')

@app.route("/deletefile",methods=["POST"])
def deletefile():
    fileName = request.json.get("fileName")
    client =MongoClient(mongo_url_to_db)
    collection = client["Task"]["DownLoadTask"]
    resopnse = {}
    try:
        collection.delete_one({"wholename":fileName})
        pathname = os.path.join(baseDir, fileName)
        if os.path.isfile(pathname):
            os.remove(pathname)
        resopnse["status"] = 200
    except:
        resopnse["status"] = 500
    return resopnse


@app.route("/getFile",methods=['GET'])
def getFile():
    filetype = request.args.get("fileType")
    filename = request.args.get("fileName")
    client =MongoClient(mongo_url_to_db)
    collection = client["Task"]["DownLoadTask"]
    dataset = {}
    dataset["wholename"] = filename+"."+filetype
    dataset["filename"] = filename
    dataset["filetype"] = filetype
    dataset["status"] = "runing"
    collection.insert_one(dataset)
    executor.submit(savefile,filename,filetype)
    # print("主线程")
    response = {}
    response["time"] = time.time()
    response["status"] = 200
    return response

def savefile(filename,filetype):
        data = []
        client =MongoClient(mongo_url_to_db)
        # 保存的文件名和文件路径
        fs = str(p.get_pinyin(filename,""))
        dbname = "doc_"+fs
        collection =client["Task"][dbname]
        with collection.find({},{'_id':0,'timestamp':0},no_cursor_timeout=True) as ret:
            for r in ret: 
                data.append(r)
        pathname = os.path.join(baseDir, fs+"."+filetype)
        with open(pathname, 'a+',encoding='utf-8') as fw:
            if filetype == "csv":
                keys = data[0].keys()
                val = ""
                for i in keys:
                    val+=i+","
                val+="\r\n"
                fw.write(val)
                for i in data:
                    val = ",".join([str(v).replace(',', '，').replace('\n', '') for v in i.values()])
                    fw.write(val+"\r\n")
            else:
                fw.write("[")
                for i in data:
                    fw.write(str(i)+"\r\n")
                fw.write("]")
        time.sleep(10)
        collection = client["Task"]["DownLoadTask"]
        collection.update_one({"wholename":filename+"."+filetype}, {"$set": {"status":"stop","size":"{:.2f}MB".format(int(os.path.getsize(pathname))/(1024*1024))}})
        # print("子线程")


@app.route("/downTaskStatus",methods=["GET"])
def getDownTaskStatus():
    response = {}
    status = request.args.get("status")
    client =MongoClient(mongo_url_to_db)
    collection = client["Task"]["DownLoadTask"]
    task = []
    if status == "stop":
        with collection.find({"status":"stop"},{'_id':0,'timestamp':0},no_cursor_timeout=True) as ret:
            for r in ret:
                task.append(r)
        collection.update_many({"status":"stop"},{"$set": {"status":"complete"}})
        response["flag"] = collection.count_documents({"status":"runing"})
    elif status == "complete":
        with collection.find({"status":"complete"},{'_id':0,'timestamp':0},no_cursor_timeout=True) as ret:
            for r in ret:
                task.append(r)
    response["task"] = task
    response["status"] = 200
    return response

# 发展趋势
@app.route('/development/chart',methods=["GET"])
def development_chart():
    taskname = request.args.get("dbname")
    dbname = "doc_"+str(p.get_pinyin(taskname,""))    
    client =MongoClient(mongo_url_to_db)
    # collection = client["Task"][dbname]
    # chartdata = EventData.developmentchart(collection, dbname,taskname)
    collection = client["Task"]["EventData"]
    chartdata = collection.find_one({"name":dbname})["developmentchart"]
    return {'status':200,"chartdata":chartdata}


@app.route('/wordcloud/cloud',methods=["GET"])
def wordcloud_cloud():
    dbname = "doc_"+str(p.get_pinyin(request.args.get("dbname"),""))    
    client =MongoClient(mongo_url_to_db)
    # collection = client["Task"][dbname]
    # 真实数据
    # JosnList = EventData.word_cloud_data(collection, dbname)
    collection = client["Task"]["EventData"]
    JosnList = collection.find_one({"name":dbname})["word_cloud_data"]
    return {"status":200,"chartdata":JosnList}

@app.route('/authentification/pie',methods=["GET"])
def authentification_pie():
    dbname = "doc_"+str(p.get_pinyin(request.args.get("dbname"),""))    
    client =MongoClient(mongo_url_to_db)
    # collection = client["Task"][dbname]
    # alldata = EventData.user(collection, dbname)
    collection = client["Task"]["EventData"]
    alldata = collection.find_one({"name":dbname})["user"]
    return {"status":200,"alldata":alldata}


# 地图
@app.route("/map",methods=["GET"])
def map():
    response = {}
    dbname = "doc_"+str(p.get_pinyin(request.args.get("dbname"),""))    
    client =MongoClient(mongo_url_to_db)
    # collection = client["Task"][dbname]
    # response["data"] = EventData.map(collection, dbname)
    collection = client["Task"]["EventData"]
    response["data"] = collection.find_one({"name":dbname})["map"]
    response["status"] = 200
    return response

# 微博类型
@app.route("/typeofweibo",methods=["GET"])
def TypeOfWeibo():
    response = {}
    taskname = request.args.get("dbname")
    dbname = "doc_"+str(p.get_pinyin(taskname,""))  
    client =MongoClient(mongo_url_to_db)
    # collection = client["Task"][dbname]
    # response["data"] = EventData.typeofweibo(collection, dbname, taskname)
    collection = client["Task"]["EventData"]
    response["data"] = collection.find_one({"name":dbname})["typeofweibo"]
    response["status"] = 200
    return response

@app.route("/<name>/dataset/<gid>")
def detail(name,gid):
    return render_template("./detail.html",name=name,gid=gid)

@app.route("/getWeiboDetail")
def weiboDetail():
    size = 50; #每页显示二十条数据
    response = {}
    canshu = {"type":"original"}
    data = []
    mainText = request.args.get('kwd')
    if len(mainText) != 0:
        canshu = demjson.decode(mainText)
    current = int(request.args.get('current'))
    dbname = "doc_"+str(p.get_pinyin(request.args.get('dbname'),""))
    client =MongoClient(mongo_url_to_db)
    collection =client["Task"][dbname]
    print(canshu)
    all_data_num = collection.count_documents(canshu)
    page = math.ceil(all_data_num / size) #总共可以分的页数
    with collection.find(canshu,{'_id':0,'timestamp':0},no_cursor_timeout=True).skip((current-1)*size).limit(size) as ret:
        for r in ret:
            r["pubTime"] = time.strftime("%Y-%m-%d %H:%M",time.localtime(r["pubTime"]))
            data.append(r)
    response["data"] = data
    response["current"] = current
    response["page"] = page
    response["status"] = 200
    return response

if __name__ == '__main__':
    app.run(host=host_run,port=run_port,debug=True)

